package common.inject;

import java.util.HashMap;
import java.util.Map;

public abstract class AbstractProvider<T> implements Provider<T>
{
    protected Key key;
    protected Provider<T> creator;
    protected Provider<T> delegate;
    protected Map<String, Object> argsMap = new HashMap<String, Object>();
    protected boolean isDelegate = false;

    public AbstractProvider()
    {
        throw new RuntimeException("Must be implemented!");
    }

    public AbstractProvider(Class<T> clazz, String name)
    {
        this(new DefaultProvider(), clazz, name);
    }

    public AbstractProvider(Class clazz)
    {
        this(clazz, null);
    }

    public AbstractProvider(Provider<T> creator, Class<T> clazz, String name)
    {
        bind(clazz, name);
        this.creator = creator;
    }

    public Provider<T> bind(Class<T> clazz, String name)
    {
        key = ((null == name) ? new Key(clazz) : new Key(clazz, name));
        return this;
    }

    public T get()
    {
        if (isDelegate && null != delegate)
        {
            return delegate.get();
        }

        return null;
    }

    public Provider<T> to(T t)
    {
        delegate = new DefaultProvider();
        delegate.to(t);
        isDelegate = true;
        return delegate;
    }

    public Class<T> bindClass()
    {
        return getKey().getClazz();
    }

    public Key getKey()
    {
        return key;
    }

    public void setKey(Key key)
    {
        this.key = key;
    }

    public Map<String, Object> getArgsMap()
    {
        return argsMap;
    }

    public Provider<T> put(String key, Object value)
    {
        getArgsMap().put(key, value);
        return this;
    }

    public void setArgsMap(Map<String, Object> argsMap)
    {
        this.argsMap = argsMap;
    }

}
